#include "stdafx.h"
#include "CppUnitTest.h"

#include <vex/core/any_allocator.h>
#include <vex/core/implementation/memory_resource_default_impl.h>
#include <vex/core/make_raw_handle.h>
#include <vex/core/allocate_raw_handle.h>
#include <cstdlib>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;


namespace tests { namespace core {

    struct test_contract : virtual public vex::core::contract::handle {
        virtual test_contract* clone(vex::core::contract::memory_resource* = nullptr) const = 0;
        VEX_PROTECT_CONTRACT(test_contract);
    };

    TEST_CLASS(allocators)
    {
        BEGIN_TEST_CLASS_ATTRIBUTE()
            TEST_CLASS_ATTRIBUTE(L"Module", L"tests.core.allocators")
            END_TEST_CLASS_ATTRIBUTE();
        VEX_TESTS_TRACKED_MEM_CHECK();
    public:
        TEST_METHOD_INITIALIZE(set_up)
        {
            VEX_TESTS_TRACKED_MEM_CHECK_START();
        }

        TEST_METHOD_CLEANUP(tear_down)
        {
            VEX_TESTS_TRACKED_MEM_CHECK_FINISH();
        }

        TEST_METHOD(malloc_free_memory_resource)
        {
            using vex::core::implementation::cstdlib_memory_resource;
            using vex::core::implementation::cstdlib_allocator;

            vex::handle_from_base<cstdlib_memory_resource, vex::unmanaged> 
                t_mr = cstdlib_allocator();

            {
                vex::core::contract::memory_resource* t_mr_handle = std::addressof(t_mr);
                auto t_memory =
                    t_mr_handle->allocate(5 * sizeof(int));

                Assert::IsNotNull(t_memory);

                t_mr_handle->deallocate(t_memory, 5 * sizeof(int));
            }
        }
    };

    //class test_impl
    //    : public test_contract
    //    , public vex::core::contract::memory_resource_owner
    //    , boost::noncopyable
    //{
    //    virtual test_impl* clone(vex::core::contract::memory_resource* p_memory = nullptr) const
    //    {
    //        return vex::core::allocate_raw_handle<test_impl>(
    //            p_memory ? p_memory : this->get_memory_resource());
    //    }
    //protected:
    //    test_impl()
    //    {
    //    }
    //    VEX_PROTECT_CONTRACT(test_impl);
    //};
}}